--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 1bbf6c5445401342069c56bae2ededc43871fc29
Parents : 28f9309
Author : Mark Qvist <bc7291552be7a58f361522990465165c>
Signature : T66BB85Valid, signed by author
Date : 2026-07-16T21:27:16+02:00
Use discovered interfaces
Changes
5 files changed, 375 insertions(+), 154 deletions(-)
Diff
diff --git a/sbapp/main.py b/sbapp/main.py
index 2c1603cd..bdcbcc6e 100644
--- a/sbapp/main.py
+++ b/sbapp/main.py
@@ -673,7 +673,8 @@ class SidebandApp(MDApp):
while self.sideband.service_available(): time.sleep(0.2)
RNS.log("Service stopped")
- def restart_service_action(self, sender):
+ def restart_service_action(self, sender=None):
+ RNS.log(f"Service restart requested")
if hasattr(self, "service_restarting") and self.service_restarting == True:
toast(f"Service restart already in progress")
else:
@@ -681,13 +682,20 @@ class SidebandApp(MDApp):
if hasattr(self, "connectivity_screen") and self.connectivity_screen != None:
self.connectivity_screen.ids.button_service_restart.disabled = True
def job():
+ RNS.log(f"Executing service restart")
if self.restart_service():
+ RNS.log("Service restarted successfully")
def tj(delta_time):
- toast(f"Service restarted successfully!")
+ toast(f"Service restarted successfully")
if hasattr(self, "connectivity_screen") and self.connectivity_screen != None:
self.connectivity_screen.ids.button_service_restart.disabled = False
Clock.schedule_once(tj, 0.1)
+ if self.app_state == SidebandApp.ACTIVE:
+ self.sideband.setstate("app.running", True)
+ self.sideband.setstate("app.foreground", True)
+ self.sideband.setstate("wants.clear_notifications", True)
else:
+ RNS.log("Service restart failed")
def tj(delta_time):
toast(f"Service restart failed")
if hasattr(self, "connectivity_screen") and self.connectivity_screen != None:
@@ -3874,6 +3882,48 @@ class SidebandApp(MDApp):
Clock.schedule_once(o, ll_ot)
Clock.schedule_once(final, ll_ft)
+ def connectivity_refresh_settings(self, sender=None):
+ if self.connectivity_ready:
+ try:
+ RNS.log(f"Refreshing connectivity settings", RNS.LOG_DEBUG)
+ self.connectivity_screen.ids.connectivity_use_local.active = self.sideband.config["connect_local"]
+ self.connectivity_screen.ids.connectivity_local_groupid.text = self.sideband.config["connect_local_groupid"]
+ self.connectivity_screen.ids.connectivity_local_ifac_netname.text = self.sideband.config["connect_local_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_local_ifac_passphrase.text = self.sideband.config["connect_local_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_use_tcp.active = self.sideband.config["connect_tcp"]
+ self.connectivity_screen.ids.connectivity_tcp_host.text = self.sideband.config["connect_tcp_host"]
+ self.connectivity_screen.ids.connectivity_tcp_port.text = str(self.sideband.config["connect_tcp_port"])
+ self.connectivity_screen.ids.connectivity_tcp_ifac_netname.text = self.sideband.config["connect_tcp_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_tcp_ifac_passphrase.text = self.sideband.config["connect_tcp_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_use_i2p.active = self.sideband.config["connect_i2p"]
+ self.connectivity_screen.ids.connectivity_i2p_b32.text = self.sideband.config["connect_i2p_b32"]
+ self.connectivity_screen.ids.connectivity_i2p_ifac_netname.text = self.sideband.config["connect_i2p_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_i2p_ifac_passphrase.text = self.sideband.config["connect_i2p_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_use_rnode.active = self.sideband.config["connect_rnode"]
+ self.connectivity_screen.ids.connectivity_rnode_ifac_netname.text = self.sideband.config["connect_rnode_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_rnode_ifac_passphrase.text = self.sideband.config["connect_rnode_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_use_modem.active = self.sideband.config["connect_modem"]
+ self.connectivity_screen.ids.connectivity_modem_ifac_netname.text = self.sideband.config["connect_modem_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_modem_ifac_passphrase.text = self.sideband.config["connect_modem_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_use_serial.active = self.sideband.config["connect_serial"]
+ self.connectivity_screen.ids.connectivity_serial_ifac_netname.text = self.sideband.config["connect_serial_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_serial_ifac_passphrase.text = self.sideband.config["connect_serial_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_use_weave.active = self.sideband.config["connect_weave"]
+ self.connectivity_screen.ids.connectivity_weave_ifac_netname.text = self.sideband.config["connect_weave_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_weave_ifac_passphrase.text = self.sideband.config["connect_weave_ifac_passphrase"]
+ self.connectivity_screen.ids.connectivity_enable_transport.active = self.sideband.config["connect_transport"]
+ self.connectivity_screen.ids.connectivity_obfuscate_hops.active = self.sideband.config["connect_obfuscate_hops"]
+ self.connectivity_screen.ids.connectivity_discover_interfaces.active = self.sideband.config["discover_interfaces"]
+ self.connectivity_screen.ids.connectivity_share_instance.active = self.sideband.config["connect_share_instance"]
+ self.connectivity_screen.ids.connectivity_local_ifmode.text = self.sideband.config["connect_ifmode_local"].capitalize()
+ self.connectivity_screen.ids.connectivity_tcp_ifmode.text = self.sideband.config["connect_ifmode_tcp"].capitalize()
+ self.connectivity_screen.ids.connectivity_i2p_ifmode.text = self.sideband.config["connect_ifmode_i2p"].capitalize()
+ self.connectivity_screen.ids.connectivity_rnode_ifmode.text = self.sideband.config["connect_ifmode_rnode"].capitalize()
+ self.connectivity_screen.ids.connectivity_modem_ifmode.text = self.sideband.config["connect_ifmode_modem"].capitalize()
+ self.connectivity_screen.ids.connectivity_serial_ifmode.text = self.sideband.config["connect_ifmode_serial"].capitalize()
+
+ except Exception as e: RNS.trace_exception(e)
+
def connectivity_init(self, sender=None):
if not self.connectivity_ready:
if not self.root.ids.screen_manager.has_screen("connectivity_screen"):
@@ -4092,103 +4142,106 @@ class SidebandApp(MDApp):
info += "For changes to connectivity to take effect, you must either restart the RNS service, or completely shut down and restart Sideband.\n"
self.connectivity_screen.ids.connectivity_info.text = info
- self.connectivity_screen.ids.connectivity_use_local.active = self.sideband.config["connect_local"]
- con_collapse_local(collapse=not self.connectivity_screen.ids.connectivity_use_local.active)
- self.connectivity_screen.ids.connectivity_local_groupid.text = self.sideband.config["connect_local_groupid"]
- self.connectivity_screen.ids.connectivity_local_ifac_netname.text = self.sideband.config["connect_local_ifac_netname"]
- self.connectivity_screen.ids.connectivity_local_ifac_passphrase.text = self.sideband.config["connect_local_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_use_tcp.active = self.sideband.config["connect_tcp"]
- con_collapse_tcp(collapse=not self.connectivity_screen.ids.connectivity_use_tcp.active)
- self.connectivity_screen.ids.connectivity_tcp_host.text = self.sideband.config["connect_tcp_host"]
- self.connectivity_screen.ids.connectivity_tcp_port.text = self.sideband.config["connect_tcp_port"]
- self.connectivity_screen.ids.connectivity_tcp_ifac_netname.text = self.sideband.config["connect_tcp_ifac_netname"]
- self.connectivity_screen.ids.connectivity_tcp_ifac_passphrase.text = self.sideband.config["connect_tcp_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_use_i2p.active = self.sideband.config["connect_i2p"]
- con_collapse_i2p(collapse=not self.connectivity_screen.ids.connectivity_use_i2p.active)
- self.connectivity_screen.ids.connectivity_i2p_b32.text = self.sideband.config["connect_i2p_b32"]
- self.connectivity_screen.ids.connectivity_i2p_ifac_netname.text = self.sideband.config["connect_i2p_ifac_netname"]
- self.connectivity_screen.ids.connectivity_i2p_ifac_passphrase.text = self.sideband.config["connect_i2p_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_use_rnode.active = self.sideband.config["connect_rnode"]
- con_collapse_rnode(collapse=not self.connectivity_screen.ids.connectivity_use_rnode.active)
- self.connectivity_screen.ids.connectivity_rnode_ifac_netname.text = self.sideband.config["connect_rnode_ifac_netname"]
- self.connectivity_screen.ids.connectivity_rnode_ifac_passphrase.text = self.sideband.config["connect_rnode_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_use_modem.active = self.sideband.config["connect_modem"]
- con_collapse_modem(collapse=not self.connectivity_screen.ids.connectivity_use_modem.active)
- self.connectivity_screen.ids.connectivity_modem_ifac_netname.text = self.sideband.config["connect_modem_ifac_netname"]
- self.connectivity_screen.ids.connectivity_modem_ifac_passphrase.text = self.sideband.config["connect_modem_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_use_serial.active = self.sideband.config["connect_serial"]
- con_collapse_serial(collapse=not self.connectivity_screen.ids.connectivity_use_serial.active)
- self.connectivity_screen.ids.connectivity_serial_ifac_netname.text = self.sideband.config["connect_serial_ifac_netname"]
- self.connectivity_screen.ids.connectivity_serial_ifac_passphrase.text = self.sideband.config["connect_serial_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_use_weave.active = self.sideband.config["connect_weave"]
- con_collapse_weave(collapse=not self.connectivity_screen.ids.connectivity_use_weave.active)
- self.connectivity_screen.ids.connectivity_weave_ifac_netname.text = self.sideband.config["connect_weave_ifac_netname"]
- self.connectivity_screen.ids.connectivity_weave_ifac_passphrase.text = self.sideband.config["connect_weave_ifac_passphrase"]
-
- self.connectivity_screen.ids.connectivity_enable_transport.active = self.sideband.config["connect_transport"]
- con_collapse_transport(collapse=not self.sideband.config["connect_transport"])
- self.connectivity_screen.ids.connectivity_enable_transport.bind(active=save_connectivity)
-
- self.connectivity_screen.ids.connectivity_obfuscate_hops.active = self.sideband.config["connect_obfuscate_hops"]
- self.connectivity_screen.ids.connectivity_obfuscate_hops.bind(active=save_connectivity)
-
- self.connectivity_screen.ids.connectivity_discover_interfaces.active = self.sideband.config["discover_interfaces"]
- self.connectivity_screen.ids.connectivity_discover_interfaces.bind(active=save_connectivity)
-
- self.connectivity_screen.ids.connectivity_share_instance.active = self.sideband.config["connect_share_instance"]
- self.connectivity_screen.ids.connectivity_share_instance.bind(active=save_connectivity)
-
- self.connectivity_screen.ids.connectivity_local_ifmode.text = self.sideband.config["connect_ifmode_local"].capitalize()
- self.connectivity_screen.ids.connectivity_tcp_ifmode.text = self.sideband.config["connect_ifmode_tcp"].capitalize()
- self.connectivity_screen.ids.connectivity_i2p_ifmode.text = self.sideband.config["connect_ifmode_i2p"].capitalize()
- self.connectivity_screen.ids.connectivity_rnode_ifmode.text = self.sideband.config["connect_ifmode_rnode"].capitalize()
- self.connectivity_screen.ids.connectivity_modem_ifmode.text = self.sideband.config["connect_ifmode_modem"].capitalize()
- self.connectivity_screen.ids.connectivity_serial_ifmode.text = self.sideband.config["connect_ifmode_serial"].capitalize()
-
- self.connectivity_screen.ids.connectivity_use_local.bind(active=save_connectivity)
- self.connectivity_screen.ids.connectivity_local_groupid.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_local_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_local_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_use_tcp.bind(active=save_connectivity)
- self.connectivity_screen.ids.connectivity_tcp_host.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_tcp_port.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_tcp_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_tcp_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_use_i2p.bind(active=save_connectivity)
- self.connectivity_screen.ids.connectivity_i2p_b32.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_i2p_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_i2p_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_use_rnode.bind(active=serial_connectivity_save)
- self.connectivity_screen.ids.connectivity_rnode_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_rnode_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_use_modem.bind(active=serial_connectivity_save)
- self.connectivity_screen.ids.connectivity_modem_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_modem_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_use_serial.bind(active=serial_connectivity_save)
- self.connectivity_screen.ids.connectivity_serial_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_serial_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_use_weave.bind(active=serial_connectivity_save)
- self.connectivity_screen.ids.connectivity_weave_ifac_netname.bind(focus=focus_save)
- self.connectivity_screen.ids.connectivity_weave_ifac_passphrase.bind(focus=focus_save)
-
- self.connectivity_screen.ids.connectivity_local_ifmode.bind(focus=ifmode_validate)
- self.connectivity_screen.ids.connectivity_tcp_ifmode.bind(focus=ifmode_validate)
- self.connectivity_screen.ids.connectivity_i2p_ifmode.bind(focus=ifmode_validate)
- self.connectivity_screen.ids.connectivity_rnode_ifmode.bind(focus=ifmode_validate)
- self.connectivity_screen.ids.connectivity_modem_ifmode.bind(focus=ifmode_validate)
- self.connectivity_screen.ids.connectivity_serial_ifmode.bind(focus=ifmode_validate)
+ try:
+ self.connectivity_screen.ids.connectivity_use_local.active = self.sideband.config["connect_local"]
+ con_collapse_local(collapse=not self.connectivity_screen.ids.connectivity_use_local.active)
+ self.connectivity_screen.ids.connectivity_local_groupid.text = self.sideband.config["connect_local_groupid"]
+ self.connectivity_screen.ids.connectivity_local_ifac_netname.text = self.sideband.config["connect_local_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_local_ifac_passphrase.text = self.sideband.config["connect_local_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_use_tcp.active = self.sideband.config["connect_tcp"]
+ con_collapse_tcp(collapse=not self.connectivity_screen.ids.connectivity_use_tcp.active)
+ self.connectivity_screen.ids.connectivity_tcp_host.text = self.sideband.config["connect_tcp_host"]
+ self.connectivity_screen.ids.connectivity_tcp_port.text = str(self.sideband.config["connect_tcp_port"])
+ self.connectivity_screen.ids.connectivity_tcp_ifac_netname.text = self.sideband.config["connect_tcp_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_tcp_ifac_passphrase.text = self.sideband.config["connect_tcp_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_use_i2p.active = self.sideband.config["connect_i2p"]
+ con_collapse_i2p(collapse=not self.connectivity_screen.ids.connectivity_use_i2p.active)
+ self.connectivity_screen.ids.connectivity_i2p_b32.text = self.sideband.config["connect_i2p_b32"]
+ self.connectivity_screen.ids.connectivity_i2p_ifac_netname.text = self.sideband.config["connect_i2p_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_i2p_ifac_passphrase.text = self.sideband.config["connect_i2p_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_use_rnode.active = self.sideband.config["connect_rnode"]
+ con_collapse_rnode(collapse=not self.connectivity_screen.ids.connectivity_use_rnode.active)
+ self.connectivity_screen.ids.connectivity_rnode_ifac_netname.text = self.sideband.config["connect_rnode_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_rnode_ifac_passphrase.text = self.sideband.config["connect_rnode_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_use_modem.active = self.sideband.config["connect_modem"]
+ con_collapse_modem(collapse=not self.connectivity_screen.ids.connectivity_use_modem.active)
+ self.connectivity_screen.ids.connectivity_modem_ifac_netname.text = self.sideband.config["connect_modem_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_modem_ifac_passphrase.text = self.sideband.config["connect_modem_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_use_serial.active = self.sideband.config["connect_serial"]
+ con_collapse_serial(collapse=not self.connectivity_screen.ids.connectivity_use_serial.active)
+ self.connectivity_screen.ids.connectivity_serial_ifac_netname.text = self.sideband.config["connect_serial_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_serial_ifac_passphrase.text = self.sideband.config["connect_serial_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_use_weave.active = self.sideband.config["connect_weave"]
+ con_collapse_weave(collapse=not self.connectivity_screen.ids.connectivity_use_weave.active)
+ self.connectivity_screen.ids.connectivity_weave_ifac_netname.text = self.sideband.config["connect_weave_ifac_netname"]
+ self.connectivity_screen.ids.connectivity_weave_ifac_passphrase.text = self.sideband.config["connect_weave_ifac_passphrase"]
+
+ self.connectivity_screen.ids.connectivity_enable_transport.active = self.sideband.config["connect_transport"]
+ con_collapse_transport(collapse=not self.sideband.config["connect_transport"])
+ self.connectivity_screen.ids.connectivity_enable_transport.bind(active=save_connectivity)
+
+ self.connectivity_screen.ids.connectivity_obfuscate_hops.active = self.sideband.config["connect_obfuscate_hops"]
+ self.connectivity_screen.ids.connectivity_obfuscate_hops.bind(active=save_connectivity)
+
+ self.connectivity_screen.ids.connectivity_discover_interfaces.active = self.sideband.config["discover_interfaces"]
+ self.connectivity_screen.ids.connectivity_discover_interfaces.bind(active=save_connectivity)
+
+ self.connectivity_screen.ids.connectivity_share_instance.active = self.sideband.config["connect_share_instance"]
+ self.connectivity_screen.ids.connectivity_share_instance.bind(active=save_connectivity)
+
+ self.connectivity_screen.ids.connectivity_local_ifmode.text = self.sideband.config["connect_ifmode_local"].capitalize()
+ self.connectivity_screen.ids.connectivity_tcp_ifmode.text = self.sideband.config["connect_ifmode_tcp"].capitalize()
+ self.connectivity_screen.ids.connectivity_i2p_ifmode.text = self.sideband.config["connect_ifmode_i2p"].capitalize()
+ self.connectivity_screen.ids.connectivity_rnode_ifmode.text = self.sideband.config["connect_ifmode_rnode"].capitalize()
+ self.connectivity_screen.ids.connectivity_modem_ifmode.text = self.sideband.config["connect_ifmode_modem"].capitalize()
+ self.connectivity_screen.ids.connectivity_serial_ifmode.text = self.sideband.config["connect_ifmode_serial"].capitalize()
+
+ self.connectivity_screen.ids.connectivity_use_local.bind(active=save_connectivity)
+ self.connectivity_screen.ids.connectivity_local_groupid.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_local_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_local_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_use_tcp.bind(active=save_connectivity)
+ self.connectivity_screen.ids.connectivity_tcp_host.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_tcp_port.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_tcp_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_tcp_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_use_i2p.bind(active=save_connectivity)
+ self.connectivity_screen.ids.connectivity_i2p_b32.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_i2p_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_i2p_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_use_rnode.bind(active=serial_connectivity_save)
+ self.connectivity_screen.ids.connectivity_rnode_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_rnode_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_use_modem.bind(active=serial_connectivity_save)
+ self.connectivity_screen.ids.connectivity_modem_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_modem_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_use_serial.bind(active=serial_connectivity_save)
+ self.connectivity_screen.ids.connectivity_serial_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_serial_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_use_weave.bind(active=serial_connectivity_save)
+ self.connectivity_screen.ids.connectivity_weave_ifac_netname.bind(focus=focus_save)
+ self.connectivity_screen.ids.connectivity_weave_ifac_passphrase.bind(focus=focus_save)
+
+ self.connectivity_screen.ids.connectivity_local_ifmode.bind(focus=ifmode_validate)
+ self.connectivity_screen.ids.connectivity_tcp_ifmode.bind(focus=ifmode_validate)
+ self.connectivity_screen.ids.connectivity_i2p_ifmode.bind(focus=ifmode_validate)
+ self.connectivity_screen.ids.connectivity_rnode_ifmode.bind(focus=ifmode_validate)
+ self.connectivity_screen.ids.connectivity_modem_ifmode.bind(focus=ifmode_validate)
+ self.connectivity_screen.ids.connectivity_serial_ifmode.bind(focus=ifmode_validate)
+ except Exception as e:
+ RNS.trace_exception(e)
else:
info = ""
@@ -4493,6 +4546,9 @@ class SidebandApp(MDApp):
def close_sub_hardware_action(self, sender=None): self.hardware_action(direction="right")
def close_hardware_action(self, sender=None): self.open_conversations(direction="right")
+ def refresh_rnode_settings(self, sender=None):
+ if self.hardware_view: self.hardware_view.refresh_rnode_parameters()
+
### Announce Stream screen
######################################
def init_announces_view(self, sender=None):
diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py
index 4f93425f..e7b23693 100644
--- a/sbapp/sideband/core.py
+++ b/sbapp/sideband/core.py
@@ -965,8 +965,8 @@ class SidebandCore():
def reload_configuration(self):
self.__reload_config()
- def save_configuration(self):
- self.__save_config()
+ def save_configuration(self, no_thread=False):
+ self.__save_config(no_thread=no_thread)
if self.is_standalone and not self.is_daemon: self.owner_app.save_window_config()
def set_active_propagation_node(self, dest):
@@ -2085,6 +2085,7 @@ class SidebandCore():
elif "incoming_messages_status" in call: connection.send(self.incoming_messages_status())
elif "inbound_count" in call: connection.send(self.inbound_count())
elif "cancel_all_inbound" in call: connection.send(self.cancel_all_inbound())
+ elif "use_interface" in call: connection.send(self._use_interface(if_data=call["use_interface"]))
elif "is_tracking" in call: connection.send(self.is_tracking(call["is_tracking"]))
elif "start_tracking" in call: connection.send(self.start_tracking(object_addr=call["start_tracking"]["object_addr"], interval=call["start_tracking"]["interval"], duration=call["start_tracking"]["duration"]))
elif "stop_tracking" in call: connection.send(self.stop_tracking(object_addr=call["stop_tracking"]["object_addr"]))
@@ -4147,6 +4148,59 @@ class SidebandCore():
self.interface_rnode = None
self.interface_rnode_adding = False
+ def _use_interface(self, if_data):
+ supported_types = ["BackboneInterface", "TCPServerInterface", "RNodeInterface"]
+ try:
+ if "type" in if_data and if_data["type"]: if_type = if_data["type"]
+ if not if_type in supported_types: return False
+ if if_type == "RNodeInterface":
+ self.config["connect_rnode"] = True
+ self.config["hw_rnode_modulation"] = "LoRa"
+ self.config["hw_rnode_frequency"] = if_data["frequency"]
+ self.config["hw_rnode_bandwidth"] = if_data["bandwidth"]
+ self.config["hw_rnode_spreading_factor"] = if_data["sf"]
+ self.config["hw_rnode_coding_rate"] = if_data["cr"]
+ self.config["connect_rnode_ifac_netname"] = str(if_data["ifac_netname"]) if "ifac_netname" in if_data and if_data["ifac_netname"] else ""
+ self.config["connect_rnode_ifac_passphrase"] = str(if_data["ifac_netkey"]) if "ifac_netkey" in if_data and if_data["ifac_netkey"] else ""
+ RNS.log(f"SAVING FROM SERVICE")
+ self.save_configuration(no_thread=True)
+ RNS.log(f"DONE")
+ return True
+
+ elif if_type == "BackboneInterface" or if_type == "TCPServerInterface":
+ self.config["connect_tcp"] = True
+ self.config["connect_tcp_host"] = str(if_data["reachable_on"])
+ self.config["connect_tcp_port"] = str(if_data["port"])
+ self.config["connect_tcp_ifac_netname"] = str(if_data["ifac_netname"]) if "ifac_netname" in if_data and if_data["ifac_netname"] else ""
+ self.config["connect_tcp_ifac_passphrase"] = str(if_data["ifac_netkey"]) if "ifac_netkey" in if_data and if_data["ifac_netkey"] else ""
+ RNS.log(f"SAVING FROM SERVICE")
+ self.save_configuration(no_thread=True)
+ RNS.log(f"DONE")
+ return True
+
+ return False
+
+ except Exception as e:
+ RNS.log(f"Error while configuring discovered interface: {e}", RNS.LOG_ERROR)
+ RNS.trace_exception(e)
+ return False
+
+ def use_interface(self, if_data):
+ if self.allow_service_dispatch and self.is_client:
+ try:
+ result = self.service_rpc_request({"use_interface": if_data })
+ self.reload_configuration()
+ RNS.log(self.config)
+ self.owner_app.connectivity_refresh_settings()
+ self.owner_app.refresh_rnode_settings()
+ return result
+ except Exception as e:
+ RNS.log("Error while setting interface configuration over RPC: "+str(e), RNS.LOG_DEBUG)
+ RNS.trace_exception(e)
+ return False
+
+ else: return False
+
def _reticulum_log_debug(self, debug=False):
self.log_verbose = debug
if self.log_quiet: selected_level = 0
diff --git a/sbapp/ui/hardware.py b/sbapp/ui/hardware.py
index 947583ae..9c4ab440 100644
--- a/sbapp/ui/hardware.py
+++ b/sbapp/ui/hardware.py
@@ -306,6 +306,61 @@ class Hardware():
self.app.sideband.save_configuration()
+ def refresh_rnode_parameters(self, sender=None):
+ if self.hardware_rnode_screen:
+ RNS.log(f"Getting RNode configuration parameters", RNS.LOG_DEBUG)
+ try:
+ if self.app.sideband.config["hw_rnode_frequency"] != None: t_freq = str(self.app.sideband.config["hw_rnode_frequency"]/1000000.0)
+ else: t_freq = ""
+
+ if self.app.sideband.config["hw_rnode_bandwidth"] != None: t_bw = str(self.app.sideband.config["hw_rnode_bandwidth"]/1000.0)
+ else: t_bw = str(62.5)
+
+ if self.app.sideband.config["hw_rnode_tx_power"] != None: t_p = str(self.app.sideband.config["hw_rnode_tx_power"])
+ else: t_p = str(0)
+
+ if self.app.sideband.config["hw_rnode_spreading_factor"] != None: t_sf = str(self.app.sideband.config["hw_rnode_spreading_factor"])
+ else: t_sf = str(8)
+
+ if self.app.sideband.config["hw_rnode_coding_rate"] != None: t_cr = str(self.app.sideband.config["hw_rnode_coding_rate"])
+ else: t_cr = str(6)
+
+ if self.app.sideband.config["hw_rnode_beaconinterval"] != None: t_bi = str(self.app.sideband.config["hw_rnode_beaconinterval"])
+ else: t_bi = ""
+
+ if self.app.sideband.config["hw_rnode_beacondata"] != None: t_bd = str(self.app.sideband.config["hw_rnode_beacondata"])
+ else: t_bd = ""
+
+ if self.app.sideband.config["hw_rnode_bt_device"] != None: t_btd = str(self.app.sideband.config["hw_rnode_bt_device"])
+ else: t_btd = ""
+
+ if self.app.sideband.config["hw_rnode_tcp_host"] != None: t_th = str(self.app.sideband.config["hw_rnode_tcp_host"])
+ else: t_th = ""
+
+ if self.app.sideband.config["hw_rnode_atl_short"] != None: t_ats = str(self.app.sideband.config["hw_rnode_atl_short"])
+ else: t_ats = ""
+
+ if self.app.sideband.config["hw_rnode_atl_long"] != None: t_atl = str(self.app.sideband.config["hw_rnode_atl_long"])
+ else: t_atl = ""
+
+ self.hardware_rnode_screen.ids.hardware_rnode_bluetooth.active = self.app.sideband.config["hw_rnode_bluetooth"]
+ self.hardware_rnode_screen.ids.hardware_rnode_ble.active = self.app.sideband.config["hw_rnode_ble"]
+ self.hardware_rnode_screen.ids.hardware_rnode_tcp.active = self.app.sideband.config["hw_rnode_tcp"]
+ self.hardware_rnode_screen.ids.hardware_rnode_framebuffer.active = self.app.sideband.config["hw_rnode_enable_framebuffer"]
+ self.hardware_rnode_screen.ids.hardware_rnode_frequency.text = t_freq
+ self.hardware_rnode_screen.ids.hardware_rnode_bandwidth.text = t_bw
+ self.hardware_rnode_screen.ids.hardware_rnode_txpower.text = t_p
+ self.hardware_rnode_screen.ids.hardware_rnode_spreadingfactor.text = t_sf
+ self.hardware_rnode_screen.ids.hardware_rnode_codingrate.text = t_cr
+ self.hardware_rnode_screen.ids.hardware_rnode_beaconinterval.text = t_bi
+ self.hardware_rnode_screen.ids.hardware_rnode_beacondata.text = t_bd
+ self.hardware_rnode_screen.ids.hardware_rnode_bt_device.text = t_btd
+ self.hardware_rnode_screen.ids.hardware_rnode_tcp_host.text = t_th
+ self.hardware_rnode_screen.ids.hardware_rnode_atl_short.text = t_ats
+ self.hardware_rnode_screen.ids.hardware_rnode_atl_long.text = t_atl
+
+ except Exception as e: RNS.trace_exception(e)
+
def hardware_rnode_init(self, sender=None):
if not self.hardware_rnode_ready:
if not self.app.root.ids.screen_manager.has_screen("hardware_rnode_screen"):
@@ -323,54 +378,7 @@ class Hardware():
if not sender.focus:
save_connectivity(sender=sender)
- if self.app.sideband.config["hw_rnode_frequency"] != None: t_freq = str(self.app.sideband.config["hw_rnode_frequency"]/1000000.0)
- else: t_freq = ""
-
- if self.app.sideband.config["hw_rnode_bandwidth"] != None: t_bw = str(self.app.sideband.config["hw_rnode_bandwidth"]/1000.0)
- else: t_bw = str(62.5)
-
- if self.app.sideband.config["hw_rnode_tx_power"] != None: t_p = str(self.app.sideband.config["hw_rnode_tx_power"])
- else: t_p = str(0)
-
- if self.app.sideband.config["hw_rnode_spreading_factor"] != None: t_sf = str(self.app.sideband.config["hw_rnode_spreading_factor"])
- else: t_sf = str(8)
-
- if self.app.sideband.config["hw_rnode_coding_rate"] != None: t_cr = str(self.app.sideband.config["hw_rnode_coding_rate"])
- else: t_cr = str(6)
-
- if self.app.sideband.config["hw_rnode_beaconinterval"] != None: t_bi = str(self.app.sideband.config["hw_rnode_beaconinterval"])
- else: t_bi = ""
-
- if self.app.sideband.config["hw_rnode_beacondata"] != None: t_bd = str(self.app.sideband.config["hw_rnode_beacondata"])
- else: t_bd = ""
-
- if self.app.sideband.config["hw_rnode_bt_device"] != None: t_btd = str(self.app.sideband.config["hw_rnode_bt_device"])
- else: t_btd = ""
-
- if self.app.sideband.config["hw_rnode_tcp_host"] != None: t_th = str(self.app.sideband.config["hw_rnode_tcp_host"])
- else: t_th = ""
-
- if self.app.sideband.config["hw_rnode_atl_short"] != None: t_ats = str(self.app.sideband.config["hw_rnode_atl_short"])
- else: t_ats = ""
-
- if self.app.sideband.config["hw_rnode_atl_long"] != None: t_atl = str(self.app.sideband.config["hw_rnode_atl_long"])
- else: t_atl = ""
-
- self.hardware_rnode_screen.ids.hardware_rnode_bluetooth.active = self.app.sideband.config["hw_rnode_bluetooth"]
- self.hardware_rnode_screen.ids.hardware_rnode_ble.active = self.app.sideband.config["hw_rnode_ble"]
- self.hardware_rnode_screen.ids.hardware_rnode_tcp.active = self.app.sideband.config["hw_rnode_tcp"]
- self.hardware_rnode_screen.ids.hardware_rnode_framebuffer.active = self.app.sideband.config["hw_rnode_enable_framebuffer"]
- self.hardware_rnode_screen.ids.hardware_rnode_frequency.text = t_freq
- self.hardware_rnode_screen.ids.hardware_rnode_bandwidth.text = t_bw
- self.hardware_rnode_screen.ids.hardware_rnode_txpower.text = t_p
- self.hardware_rnode_screen.ids.hardware_rnode_spreadingfactor.text = t_sf
- self.hardware_rnode_screen.ids.hardware_rnode_codingrate.text = t_cr
- self.hardware_rnode_screen.ids.hardware_rnode_beaconinterval.text = t_bi
- self.hardware_rnode_screen.ids.hardware_rnode_beacondata.text = t_bd
- self.hardware_rnode_screen.ids.hardware_rnode_bt_device.text = t_btd
- self.hardware_rnode_screen.ids.hardware_rnode_tcp_host.text = t_th
- self.hardware_rnode_screen.ids.hardware_rnode_atl_short.text = t_ats
- self.hardware_rnode_screen.ids.hardware_rnode_atl_long.text = t_atl
+ self.refresh_rnode_parameters()
self.hardware_rnode_screen.ids.hardware_rnode_frequency.bind(focus=focus_save)
self.hardware_rnode_screen.ids.hardware_rnode_bandwidth.bind(focus=focus_save)
self.hardware_rnode_screen.ids.hardware_rnode_txpower.bind(focus=focus_save)
diff --git a/sbapp/ui/objectdetails.py b/sbapp/ui/objectdetails.py
index 5b18f758..932a5cf6 100644
--- a/sbapp/ui/objectdetails.py
+++ b/sbapp/ui/objectdetails.py
@@ -65,6 +65,18 @@ class ObjectDetails():
self.telemetry_list.app = self.app
self.screen.ids.object_details_container.add_widget(self.telemetry_list)
+ self.telemetry_request_buttons = None
+ self.tracking_buttons = None
+ self.interface_buttons = None
+ self.screen.ids.telemetry_request_buttons._target_meta = "telemetry_request_buttons"
+ self.screen.ids.tracking_buttons._target_meta = "tracking_buttons"
+ self.screen.ids.interface_buttons._target_meta = "interface_buttons"
+ for w in self.screen.ids.details_screen_container.children:
+ if hasattr(w, "_target_meta"):
+ if w._target_meta == "telemetry_request_buttons": self.telemetry_request_buttons = w
+ elif w._target_meta == "tracking_buttons": self.tracking_buttons = w
+ elif w._target_meta == "interface_buttons": self.interface_buttons = w
+
ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
self.info_dialog = MDDialog(title="Info", text="", buttons=[ ok_button ])
@@ -95,11 +107,9 @@ class ObjectDetails():
if self.delete_dialog == None:
yes_button = MDRectangleFlatButton(text="Yes",font_size=dp(18), theme_text_color="Custom", line_color=self.app.color_reject, text_color=self.app.color_reject)
no_button = MDRectangleFlatButton(text="No",font_size=dp(18))
- self.delete_dialog = MDDialog(
- title="Clear telemetry?",
- text="This will permanently delete all collected telemetry for this object.",
- buttons=[ yes_button, no_button ],
- )
+ self.delete_dialog = MDDialog(title="Clear telemetry?", buttons=[ yes_button, no_button ],
+ text="This will permanently delete all collected telemetry for this object.")
+
def dl_yes(s):
self.delete_dialog.dismiss()
self.confirm_delete_telemetry()
@@ -120,6 +130,52 @@ class ObjectDetails():
self.set_source(self.object_hash, from_conv=self.from_conv, from_objects=self.from_objects, from_telemetry=self.from_telemetry)
if not notoast: toast("Reloaded telemetry for object")
+ def use_interface_action(self, sender=None):
+ if not RNS.vendor.platformutils.is_android():
+ if not RNS.vendor.platformutils.is_windows(): cp = str(RNS.Reticulum.configpath)
+ else: cp = str(RNS.Reticulum.configpath.replace("/", "\\"))
+ self.info_dialog.title = "Interface Configuration"
+ self.info_dialog.text = f"On desktop operating systems, interface configuration is handled by Reticulum. To use this interface, copy the configuration to your Reticulum configuration file located at:\n\n{cp}\n\nOn Android, interfaces can be configured directly with this button."
+ self.info_dialog.open()
+
+ else:
+ if not self.viewing_interface or not self.interface_data: return
+ else:
+ success = False
+ r_str = f"\n\nReticulum is restarting, and the new interface should be available shortly."
+ if_type = self.interface_data["type"] if "type" in self.interface_data else "unknown interface"
+ if_name = self.interface_data["name"] if "name" in self.interface_data and self.interface_data["name"] else f"discovered {if_type}"
+ if if_type == "RNodeInterface":
+ if self.app.sideband.use_interface(self.interface_data):
+ self.info_dialog.title = "Interface Configured"
+ self.info_dialog.text = f"RNode parameters configured to use [b]{if_name}[/b]{r_str}"
+ success = True
+ else:
+ self.info_dialog.title = "Configuration Error"
+ self.info_dialog.text = f"The configuration parameters were not valid."
+ self.info_dialog.open()
+ elif if_type == "BackboneInterface" or if_type == "TCPServerInterface":
+ if self.app.sideband.use_interface(self.interface_data):
+ self.info_dialog.title = "Interface Configured"
+ self.info_dialog.text = f"TCP connection parameters configured to use [b]{if_name}[/b]{r_str}"
+ success = True
+ else:
+ self.info_dialog.title = "Configuration Error"
+ self.info_dialog.text = f"The configuration parameters were not valid."
+ self.info_dialog.open()
+ else:
+ if not if_type:
+ self.info_dialog.title = "Invalid Interface"
+ self.info_dialog.text = f"The announced interface data is invalid. Cannot use for auto-configuration."
+ else:
+ self.info_dialog.title = "Unsupported Interface"
+ self.info_dialog.text = f"The interface type {if_type} is not supported for auto-configuration."
+ self.info_dialog.open()
+
+ if success:
+ def cb(dt): self.app.restart_service_action()
+ Clock.schedule_once(cb, 1.0)
+
def get_interface_data(self, discovery_hash):
ifs = self.app.list_discovered_interfaces()
if not ifs: return None, None, None, None
@@ -160,12 +216,14 @@ class ObjectDetails():
self.interface_lat = if_data["latitude"] if "latitude" in if_data else None
self.interface_lon = if_data["longitude"] if "longitude" in if_data else None
self.interface_config = if_data["config_entry"] if "config_entry" in if_data else None
+ self.interface_data = if_data
else:
self.viewing_interface = False
self.interface_lat = None
self.interface_lon = None
self.interface_config = None
+ self.interface_data = None
if from_telemetry: self.from_telemetry = True
else:
@@ -176,6 +234,25 @@ class ObjectDetails():
if from_objects: self.from_objects = True
else: self.from_objects = False
+ if self.viewing_interface:
+ if self.telemetry_request_buttons in self.screen.ids.details_screen_container.children:
+ self.screen.ids.details_screen_container.remove_widget(self.telemetry_request_buttons)
+ if self.tracking_buttons in self.screen.ids.details_screen_container.children:
+ self.screen.ids.details_screen_container.remove_widget(self.tracking_buttons)
+ if not self.interface_buttons in self.screen.ids.details_screen_container.children:
+ self.screen.ids.details_screen_container.add_widget(self.interface_buttons)
+
+ if if_data and "type" in if_data:
+ if if_data["type"] == "RNodeInterface": self.screen.ids.use_interface_button.icon = "radio-handheld"
+ else: self.screen.ids.use_interface_button.icon = "lan-connect"
+ else:
+ if self.interface_buttons in self.screen.ids.details_screen_container.children:
+ self.screen.ids.details_screen_container.remove_widget(self.interface_buttons)
+ if not self.telemetry_request_buttons in self.screen.ids.details_screen_container.children:
+ self.screen.ids.details_screen_container.add_widget(self.telemetry_request_buttons)
+ if not self.tracking_buttons in self.screen.ids.details_screen_container.children:
+ self.screen.ids.details_screen_container.add_widget(self.tracking_buttons)
+
if self.viewing_self: self.screen.ids.track_button.disabled = True
else:
self.screen.ids.track_button.disabled = False
@@ -957,6 +1034,7 @@ MDScreen:
name: "object_details_screen"
BoxLayout:
+ id: details_screen_container
orientation: "vertical"
MDTopAppBar:
@@ -1039,6 +1117,7 @@ MDScreen:
height: dp(1)
MDBoxLayout:
+ id: telemetry_request_buttons
orientation: "horizontal"
spacing: dp(24)
size_hint_y: None
@@ -1068,6 +1147,7 @@ MDScreen:
disabled: False
MDBoxLayout:
+ id: tracking_buttons
orientation: "horizontal"
spacing: dp(16)
size_hint_y: None
@@ -1084,5 +1164,26 @@ MDScreen:
size_hint: [1.0, None]
on_release: root.delegate.live_tracking(self)
disabled: False
+
+
+
+ MDBoxLayout:
+ id: interface_buttons
+ orientation: "horizontal"
+ spacing: dp(24)
+ size_hint_y: None
+ height: self.minimum_height
+ padding: [dp(24), dp(24), dp(24), dp(24)]
+
+ MDRectangleFlatIconButton:
+ id: use_interface_button
+ icon: "lan-connect"
+ text: "Use Interface"
+ padding: [dp(0), dp(14), dp(0), dp(14)]
+ icon_size: dp(24)
+ font_size: dp(16)
+ size_hint: [1.0, None]
+ on_release: root.delegate.use_interface_action()
+ disabled: False
"""
\ No newline at end of file
diff --git a/sbapp/ui/utilities.py b/sbapp/ui/utilities.py
index e4003deb..34b0ab62 100644
--- a/sbapp/ui/utilities.py
+++ b/sbapp/ui/utilities.py
@@ -116,6 +116,8 @@ class Utilities():
self.rnstatus_instance.main(rns_instance=RNS.Reticulum.get_instance())
output = buffer.getvalue()
+ output = output.replace("↑", "tx ").replace("↓", "rx ")
+
def cb(dt):
self.rnstatus_screen.ids.rnstatus_output.text = f"[font=RobotoMono-Regular][size={int(dp(12))}]{output}[/size][/font]"
Clock.schedule_once(cb, 0.2)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────